from playwright.sync_api import sync_playwright
import time
import subprocess
import os
from loguru import logger
import traceback
import requests
import datetime

class Amazon:
    def __init__(self, playwright):
        self.playwright = playwright
        self.json_dir = os.path.join(os.getcwd(), 'json')
        if not os.path.exists(self.json_dir):
            os.makedirs(self.json_dir)
        self.server_url = 'http://192.168.3.49:8990'

    def wait(self, page, seconds=1):
        page.wait_for_load_state(state="domcontentloaded")
        time.sleep(seconds)

    def connection_browser(self):
        chromium = playwright.chromium.connect_over_cdp(r"http://localhost:9001")
        self.context = chromium.contexts[0]

    def login(self):
        try:
            # os.system('taskkill /F /IM chrome.exe')
            # time.sleep(3)
            # command = r"C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-port=9001 --user-data-dir=D:\playwright_chrome -–start-maximized"
            # print("浏览器路径：", command)
            # subprocess.Popen(command)
            # time.sleep(5)
            self.connection_browser()
            self.page = self.context.pages[0]
            self.page.goto('https://sellercentral.amazon.com/home')
            self.wait(self.page)
            self.page.fill('#ap_email', 'szyy@tjwanda.com')
            time.sleep(0.5)
            self.page.query_selector('input[id="continue"]').click()
            self.wait(self.page)
            time.sleep(1)
            self.page.fill('#ap_password', '!QAZ2wsx')
            time.sleep(0.5)
            self.page.click('#signInSubmit')
            self.wait(self.page)
            # 手机验证码处理
            self.check_sms_code()
            # 选择账户
            logger.info('选择账户...')
            self.page.query_selector('div.picker-name:has-text("美国")').click()
            self.page.query_selector('button.picker-switch-accounts-button').click()
            self.wait_for_loading(self.page, 'div[data-test-tag="nav-button-container"]')
            logger.info('登录成功')
            return True
        except:
            logger.info(traceback.format_exc())

    def get_sell_goods_data(self):
        logger.info('开始获取销售价格流程...')
        self.connection_browser()
        godds_price_list = []
        # 滚到页面底部
        new_page = self.context.new_page()
        new_page.goto('https://sellercentral.amazon.com/myinventory/inventory?ref_=xx_invmgr_dnav_xx')
        self.wait_for_loading(new_page, '#filtersContainer')
        time.sleep(1)
        new_page.query_selector('#filtersContainer >> kat-dropdown').click()
        logger.info('点击商品状态，选择在售商品...')
        with new_page.expect_request('https://sellercentral.amazon.com/revenuecalculator/getbatchfeesamount') as res:
            new_page.query_selector('kat-option:has-text("在售"):visible').click()
        req = res.value
        post_data = req.post_data_json
        logger.info(f'第【1】页共【{len(post_data["feesAmountRequestList"])}】条数据...')
        if len(post_data["feesAmountRequestList"]) > 0:
            for data in post_data['feesAmountRequestList']:
                godds_price_list.append(self.build_goods_price_data(data))
        else:
            return godds_price_list
        # 滚到页面底部
        for k in range(5):
            new_page.keyboard.press('End')
            time.sleep(1)
        page = 2
        class_name = new_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
        while 'end' not in class_name:
            with new_page.expect_request(
                    'https://sellercentral.amazon.com/revenuecalculator/getbatchfeesamount') as res:
                new_page.query_selector('span[part="pagination-nav-right"]').click()
            req = res.value
            post_data = req.post_data_json
            logger.info(f'第【{page}】页共【{len(post_data["feesAmountRequestList"])}】条数据...')
            if len(post_data['feesAmountRequestList']) == 0:
                break
            else:
                for data in post_data['feesAmountRequestList']:
                    godds_price_list.append(self.build_goods_price_data(data))
            # 滚到页面底部
            for k in range(5):
                new_page.keyboard.press('End')
                time.sleep(1)
            class_name = new_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
            page += 1
        logger.info('商品价格信息')
        logger.info(godds_price_list)
        new_page.close()
        return godds_price_list

    # 组装商品价格数据
    def build_goods_price_data(self, data):
        item = {'sku': '', 'asin': '', 'price': 0, 'recommendPrice': 0}
        # sku
        if 'mSku' in data.keys():
            item['sku'] = data['mSku']
        # asin
        if 'asin' in data.keys():
            item['asin'] = data['asin']
        # 价格
        if 'itemPrice' in data.keys():
            item['price'] = data['itemPrice']
        # 推荐报价：如果 salePrice 不为空，取 salePrice，否则取 itemPrice
        if 'salePrice' in data.keys() and str(data['salePrice']).strip() != '':
            item['recommendPrice'] = data['salePrice']
        else:
            item['recommendPrice'] = item['price']
        return item

    # 获取优惠券数据
    def get_yhq_data(self):
        logger.info('开始获取优惠券流程...')
        self.connection_browser()
        new_page = self.context.new_page()
        logger.info('打开优惠券页面...')
        new_page.goto('https://sellercentral.amazon.com/coupons/ref=xx_scoupn_dnav_xx')
        self.wait_for_loading(new_page, 'kat-dropdown[placeholder="状态"]')
        self.wait(new_page)
        logger.info('点击状态，选择【正在进行】...')
        new_page.query_selector('kat-dropdown[placeholder="状态"]').click()
        time.sleep(1)
        new_page.query_selector('kat-option:has-text("正在进行")').click()
        time.sleep(1)
        with new_page.expect_response('https://sellercentral.amazon.com/coupons/api/getCouponPromotions?*') as res:
            new_page.query_selector('#pending-apply:visible').click(timeout=3000)
        response = res.value
        total = response.json()['promotionTotalCount']
        logger.info(f'第1页共查询到【{total}】条数据')
        if total == 0:
            return []
        link_list = []
        # 获取表格列表
        tr_list = new_page.query_selector_all('kat-data-table >> tbody >> tr')
        for tr in tr_list:
            href = tr.query_selector('kat-link').get_attribute('href')
            link = 'https://sellercentral.amazon.com' + href
            link_list.append(link)
        # 滚到页面底部
        new_page.keyboard.press('End')
        time.sleep(1)
        page = 2
        class_name = new_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
        while 'end' not in class_name:
            with new_page.expect_response('https://sellercentral.amazon.com/coupons/api/getCouponPromotions?*') as res:
                new_page.query_selector('span[part="pagination-nav-right"]').click(timeout=3000)
            response = res.value
            total = response.json()['promotionTotalCount']
            logger.info(f'第【{page}】页共查询到【{total}】条数据')
            if total == 0:
                break
            # 获取表格列表
            tr_list = new_page.query_selector_all('kat-data-table >> tbody >> tr')
            for tr in tr_list:
                href = tr.query_selector('kat-link').get_attribute('href')
                link = 'https://sellercentral.amazon.com' + href
                link_list.append(link)
            # 滚到页面底部
            new_page.keyboard.press('End')
            time.sleep(1)
            class_name = new_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
            # 页码+1
            page += 1
        data_list = self.open_and_get_yhq_detail(link_list)
        logger.info('优惠券信息')
        logger.info(data_list)
        new_page.close()
        return data_list

    # 循环链接，一个一个打开页面抓取信息
    def open_and_get_yhq_detail(self, link_list):
        data_list = []
        for link in link_list:
            info_page = self.context.new_page()
            info_page.goto(link)
            self.wait_for_loading(info_page, 'div.details-status')
            self.wait(info_page)
            title = info_page.query_selector('div.coupon-title-badge').text_content()
            logger.info(f'正在抓取【{title}】的优惠券信息...')
            # 折扣
            discount_text = ''
            discount_obj = info_page.query_selector(
                'div.details-row:has(div.details-row-header:text-is("折扣")) >> div.details-row-content')
            if discount_obj is not None:
                discount_text = discount_obj.text_content()
            # 商品数量
            product_text = info_page.query_selector('kat-tab[tab-id="products"]').text_content()
            logger.info(product_text)
            # ASIN
            asin_list = info_page.query_selector_all('table >> tbody >> tr')
            for asin_tr in asin_list:
                data = {}
                asin = asin_tr.query_selector('td.view-asin-column').text_content()
                data['asin'] = asin
                data['discount'] = discount_text
                data_list.append(data)
            # 关闭页面
            info_page.close()
            time.sleep(1)
        return data_list

    def get_prime_member_data(self):
        logger.info('开始获取Prime专享折扣流程...')
        self.connection_browser()
        new_page = self.context.new_page()
        new_page.goto('https://sellercentral.amazon.com/prime-discounts')
        self.wait_for_loading(new_page, '#templateDownloadLink')
        self.wait(new_page)
        tr_list = new_page.query_selector_all('#promotionTable >> tbody >> tr')
        logger.info(f'第1页共【{len(tr_list)}】条数据')
        if len(tr_list) == 0:
            return []
        link_list = []
        for tr in tr_list:
            status = tr.query_selector('span.cbp-status-text').text_content()
            if status == '已过期':
                continue
            href = tr.query_selector('td >> a').get_attribute('href')
            link = 'https://sellercentral.amazon.com' + href
            link_list.append(link)
        page = 2
        class_name = new_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
        while 'end' not in class_name:
            with new_page.expect_response('https://sellercentral.amazon.com/prime-discounts/ajax/fetch/promoListing?*') as res:
                new_page.query_selector('span[part="pagination-nav-right"]').click(timeout=3000)
            response = res.value
            time.sleep(1)
            tr_list = new_page.query_selector_all('#promotionTable >> tbody >> tr')
            logger.info(f'第{page}页共【{len(tr_list)}】条数据')
            for tr in tr_list:
                status = tr.query_selector('span.cbp-status-text').text_content()
                if status == '已过期':
                    continue
                href = tr.query_selector('td >> a').get_attribute('href')
                link = 'https://sellercentral.amazon.com' + href
                link_list.append(link)
            # 页码+1
            page += 1
            class_name = new_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
        logger.info(f'未过期的会员折扣个数：{len(link_list)}')
        if len(link_list) == 0:
            return []
        # 循环链接，逐个获取会员折扣数据
        data_list = []
        for link in link_list:
            for c in range(2):
                try:
                    asin_list = self.open_and_get_member_discount_data(link)
                    data_list = data_list + asin_list
                    break
                except:
                    logger.info(traceback.format_exc())
                    logger.info('获取会员折扣异常，尝试重新获取')
        logger.info('会员折扣数据')
        logger.info(data_list)
        new_page.close()
        return data_list

    def open_and_get_member_discount_data(self, link):
        data_list = []
        info_page = self.context.new_page()
        info_page.goto(link)
        self.wait_for_loading(info_page, 'h2')
        self.wait(info_page)
        title = info_page.query_selector('h2').text_content().replace('\n', '').strip()
        logger.info(f'正在抓取【{title}】的会员折扣信息...')
        # 表格数据
        asin_list = info_page.query_selector_all('#submittedTable >> table >> tbody >> tr')
        logger.info('获取第1页数据')
        for asin_tr in asin_list:
            data = {}
            status = asin_tr.query_selector('span.cbp-status-text').text_content()
            if '已过期' == status:
                continue
            # ASIN
            asin = asin_tr.query_selector('td[data-name="asin"]').get_attribute('data-value')
            data['asin'] = asin
            # 折扣
            discount = asin_tr.query_selector('td[data-name="benefitPrice"]').get_attribute('data-value')
            data['discount'] = discount
            data_list.append(data)
        class_name = info_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
        page = 2
        if class_name is not None and class_name != '':
            while 'end' not in class_name:
                with info_page.expect_response(
                        'https://sellercentral.amazon.com/prime-discounts/ajax/fetch/submitted*') as res:
                    info_page.query_selector('span[part="pagination-nav-right"]').click(timeout=3000)
                response = res.value
                time.sleep(1)
                logger.info(f'获取第{page}页数据')
                # 表格数据
                asin_list = info_page.query_selector_all('#submittedTable >> table >> tbody >> tr')
                if len(asin_list) == 0:
                    break
                for asin_tr in asin_list:
                    data = {}
                    status = asin_tr.query_selector('span.cbp-status-text').text_content()
                    if '已过期' == status:
                        continue
                    # ASIN
                    asin = asin_tr.query_selector('td[data-name="asin"]').get_attribute('data-value')
                    data['asin'] = asin
                    # 折扣
                    discount = asin_tr.query_selector('td[data-name="benefitPrice"]').get_attribute('data-value')
                    data['discount'] = discount
                    data_list.append(data)
                # 页码+1
                page += 1
                class_name = info_page.query_selector('span[part="pagination-nav-right"]').get_attribute('class')
        # 关闭页面
        info_page.close()
        time.sleep(1)
        return data_list

    # 上传到服务器
    def upload_file(self, sale_list, preferential_list, discount_list):
        '''
        :param sale_list: 在售商品价格数据
        :param preferential_list: 优惠券数据
        :param discount_list: 会员折扣数据
        :return:
        '''
        try:
            sale_file = os.path.join(self.json_dir, 'sale.json')
            preferential_file = os.path.join(self.json_dir, 'preferential.json')
            discount_file = os.path.join(self.json_dir, 'discount.json')
            # 删除历史文件
            if os.path.exists(sale_file):
                os.remove(sale_file)
            if os.path.exists(preferential_file):
                os.remove(preferential_file)
            if os.path.exists(discount_file):
                os.remove(discount_file)
            # 生成文件
            with open(sale_file, 'w') as f:
                f.write(str(sale_list))
            f.close()
            with open(preferential_file, 'w') as f:
                f.write(str(preferential_list))
            f.close()
            with open(discount_file, 'w') as f:
                f.write(str(discount_list))
            f.close()
            files = [
                ('saleFile', (open(sale_file, 'rb'))),
                ('preferentialFile', (open(preferential_file, 'rb'))),
                ('discountFile', (open(discount_file, 'rb')))
            ]
            res = requests.request('POST', self.server_url + '/api/v1/amazonBill/sysAmazonRPAImport/44', files=files)
            logger.info(res.text)
        except:
            logger.info(traceback.format_exc())

    def check_sms_code(self):
        pass

    def wait_for_loading(self, page, path):
        for c in range(20):
            try:
                if page.query_selector(path) is not None:
                    break
                time.sleep(1)
                logger.info(f'等待页面加载【{c + 1}】秒')
            except:
                pass

    def run(self):
        log_path = os.path.join(os.getcwd(), 'logs')
        if not os.path.exists(log_path):
            os.makedirs(log_path)
        logger.add(os.path.join(log_path, f'amazon_goods_{datetime.datetime.now().strftime("%Y-%m-%d")}.txt'))
        # sale_list = self.get_sell_goods_data()
        # preferential_list = self.get_yhq_data()
        # discount_list = self.get_prime_member_data()
        # self.upload_file(sale_list, preferential_list, discount_list)
        files = [
            ('saleFile', (open(r'D:\amazon-python-server\amazon_rpa\json\sale.json', 'rb'))),
            ('preferentialFile', (open(r'D:\amazon-python-server\amazon_rpa\json\preferential.json', 'rb'))),
            ('discountFile', (open(r'D:\amazon-python-server\amazon_rpa\json\discount.json', 'rb')))
        ]
        res = requests.request('POST', self.server_url + '/api/v1/amazonBill/sysAmazonRPAImport/44', files=files)
        logger.info(res.text)

with sync_playwright() as playwright:
    amazon = Amazon(playwright)
    amazon.run()

